home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c++-part2 / 14251 < prev    next >
Encoding:
Internet Message Format  |  1996-08-05  |  3.9 KB

  1. Path: newshost.centrum.is!news
  2. From: bjarnir@centrum.is (Bjarni Ragnarsson)
  3. Newsgroups: comp.lang.c++
  4. Subject: Re: How do you return values from in-line asm?
  5. Date: 29 Mar 1996 17:35:42 GMT
  6. Organization: BR Software
  7. Message-ID: <4jh71e$iq8@newshost.centrum.is>
  8. References: <4j9mab$19si@usenetp1.news.prodigy.com>
  9. NNTP-Posting-Host: tungl-48.centrum.is
  10. X-Newsreader: WinVN version 0.82
  11.  
  12. In article <4j9mab$19si@usenetp1.news.prodigy.com>, XKWR65B@prodigy.com (Mark Rubelmann) says:
  13. >
  14. >
  15. >Hey there! I got this book that is about programming games in C but I 
  16. >have Borland C++ v3.0 and some of the stuff doesn't work quite right. 
  17. >Most of the things I have been able to figure out on my own but I'm 
  18. >having trouble returning values from an inline assembly function. Here's 
  19. >the code that's in the book:
  20. >
  21. >unsigned char Get_Scan_Code(void)
  22. >{
  23. >asm {
  24. >     mov ah,01h        //Function 1: is a key ready?
  25. >     int 16h                // Call interrupt
  26. >     jz empty             // No key, exit
  27. >     mov ah,00h        // Function 0: get scan code
  28. >     int 16h                // Call interrupt
  29. >     mov al,ah           // result was in ah so put it in al
  30. >     xor ah,ah            // zero out ah
  31. >     jmp done            // the data's in ax    (??? ax???)
  32. >     
  33. >empty:
  34. >     xor ax,ax            // clear out ax, 0 means no key
  35. >done:
  36. >     }
  37. >}
  38. >
  39. >
  40. >First of all, I just don't understand how the resut went from al to ax. 
  41. >Also, I know the line labels should be outside of the asm statement but 
  42. >that's the way it was in the book. I've tried fooling around with ret and 
  43. >stuff like that but I can't get it to work. The compiler always gives a 
  44. >warning that it should return a value. When I try to use the function in 
  45. >something like:
  46. >
  47. >     while(Get_Scan_Code==0) {}
  48. >
  49. >but it doesn't work, it just goes on to the next statement. Any help 
  50. >would be appreciated.
  51. >
  52. >
  53.  
  54. First of all, "ax" is a two-byte register.  The high-byte is "ah" and the low byte is "al".  
  55. Any changes to ax affects either al, ah or both and vice versa.
  56. The same goes for BX=BH BL  and CX=CL CH etc....
  57.  
  58. In the code, al is set to ah and ah then set to Zero.    That is, the high byte of ax is
  59. copied to the low byte and the high byte is then zeroed.
  60.  
  61.  
  62. As to the labels, I believe inline labels in Borland can only be C labels, and thus 
  63. must be declared outside the asm block.  The asm code can use them just the
  64. same, with the exeption that it must be within the same function.  The compiler 
  65. decides weather pointers are FAR or SHORT.
  66.  
  67. Note that the code returns the scan-code in register ax (the low byte, al).  
  68. For the function to returna value that value must be placed in a specific address 
  69. (if I remember correctly).
  70.  
  71. The easiest and probably the most efficient way to handle this is to let the compiler
  72. do the job for you.  Simply add 
  73.  
  74.     return _AL;
  75.  
  76. at the end of the function (outside the asm block).  This returns the value in register
  77. al.   Note that the function returns unsigned char which is one byte.  AX is two bytes.
  78.  
  79. _AL (_AX, _AH etc.) are register pseudovariables in Borland C++.
  80.  
  81. Can't see at a glance the use of setting ax as only half of it iss needed.   
  82. Perhaps this is a part of a code which needs ax  to be set.
  83.  
  84. The suggested code:
  85.  
  86. unsigned char Get_Scan_Code(void)
  87. {
  88. asm {
  89.      mov ah,01h       //Function 1: is a key ready?
  90.      int 16h                // Call interrupt
  91.      jz empty             // No key, exit
  92.      mov ah,00h       // Function 0: get scan code
  93.      int 16h                // Call interrupt
  94.                       // Don't let's copy ah to al.  Let's use ah directly.
  95.                   // Don't zero out ah or al  as we only use ah to return a value.
  96.      jmp done           // the data's in ah 
  97.   }  
  98.  
  99. empty:                        // Keep label outside block.
  100.     asm  xor ah,ah     // clear out ah, 0 means no key
  101. done:
  102.  
  103. return _AH;        // ah is returned instead of ax.
  104.  
  105. }
  106.  
  107. Hope this is of some help,
  108. Bjarni Ragnarsson
  109. bjarnir@centrum.is
  110.  
  111.  
  112.  
  113.  
  114.  
  115.